/**
 * <p>Title: PersistenceImpl.java</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2009</p>
 * <p>Company: xunjie</p>
 * @author shenhao
 * @date 2010-3-8
 * @version 1.0
 */
package cn.haona.game.simb.object;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.haona.db.RelevanceBean;
import cn.haona.game.simb.object.god.MainManager;
import cn.haona.reflect.ReflectionBasic;

/**
 * <p>
 * Title: PersistenceImpl持久化实例
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Company: xunjie
 * </p>
 * 
 * @author shenhao
 * @date 2010-3-8
 */
public abstract class PersistenceImpl implements Serializable, Persistence {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6405782497322052623L;

	final public static String ID = "ID";

	/**
	 * 
	 */
	protected Long id = NO_ID;
	protected Timestamp addedDate;
	protected Timestamp updateDate;
	protected Integer status;
	//昵称
	protected String name;

	// 表名
	private String tableName;

	// 反射关联
	public HashMap<String, RelevanceBean> reflectRelevance = new HashMap<String, RelevanceBean>();

	/**
	 * 设置基础的反射关联
	 * 
	 * @param reflectRelevance
	 */
	public void setReflectRelevance(
			HashMap<String, RelevanceBean> reflectRelevance) {
		reflectRelevance.put(ID, new RelevanceBean("id", ID));
		reflectRelevance.put(ADDEDON, new RelevanceBean("addedDate", ADDEDON));
		reflectRelevance.put(UPDATEON,new RelevanceBean("updateDate", UPDATEON));
		reflectRelevance.put(STATUS, new RelevanceBean("status", STATUS));
	    reflectRelevance.put(NAME, new RelevanceBean("name", NAME));
	}

	// 返回反射关联集合
	public HashMap<String, RelevanceBean> getReflectRelevance() {
		return reflectRelevance;
	}

	public String getPrimaryKeyName() {
		return ID;
	}

	public PersistenceImpl() {
		initMe();
	}
	

	//初始化表名
	protected void initTableName()
	{
		// 设置表名
		try {
			tableName = (String) ReflectionBasic.getStaticProperty(getClass()
					.getName(), "TABLE_NAME");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void initMe() {
		initTableName();
		setReflectRelevance(reflectRelevance);
	}

	public PersistenceImpl(String tableName) {
		setTableName(tableName);
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Timestamp getAddedDate() {
		return addedDate;
	}

	public void setAddedDate(Timestamp addedDate) {
		this.addedDate = addedDate;
	}

	public Timestamp getUpdateDate() {
		return updateDate;
	}

	public void setUpdateDate(Timestamp updateDate) {
		this.updateDate = updateDate;
	}

	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 缓存我
	 */
	public boolean cacheMe() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * 更新我
	 */
	public Persistence updateMe() {

		Connection conn = MainManager.getInstance().getPersistenceManager()
				.getDB_Connection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		String sql = "select * from " + getTableName() + " where "
				+ getPrimaryKeyName() + "=?";
		try {
			ps = conn.prepareStatement(sql);
			ps.setLong(1, getId());
			rs = ps.executeQuery();
			// 如果有这个家伙
			if (rs.next()) {
				// 得到反射关联
				HashMap<String, RelevanceBean> reflectRelevance = getReflectRelevance();
				// 得到反射关联迭代器
				Iterator iterRR = reflectRelevance.entrySet().iterator();
				// 迭代
				while (iterRR.hasNext()) {
					Map.Entry entry = (Map.Entry) iterRR.next();
					String key = (String) entry.getKey();
					RelevanceBean rBean = (RelevanceBean) entry.getValue();
					// 得到数据库字段所对应的值
					// 如果不是主键
					if (!rBean.isPrimary) {
						Object objPersis = rs.getObject(rBean.getFieldName());
						// 如果持久化数据库有这个参数
						if (objPersis != null) {
							String paramName = rBean.getParamName();
							// 改变参数首字母为大写
							paramName = "set"
									+ ReflectionBasic
											.changeHeadLetterUpper(paramName);

							// System.out.println("paramKey=" + paramName
							// + ";value=" + objPersis);
							// 填充该对象的参数
							ReflectionBasic.invokeMethod(this, paramName,
									new Object[] { objPersis });
						}// end if(如果持久化数据库有这个参数)
					}
				}// end while(迭代)

				return this;
			}// end if(如果有这个家伙)

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
				if (ps != null) {
					ps.close();
				}
				if (conn != null) {
					conn.close();
				}

			} catch (Exception e) {
				{
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 更新参数
	 * 
	 * @param keyName
	 * @param param
	 * @return TODO
	 */
	public boolean persisParam(String keyName, Object param) {

		// 如果有ID
		if (getId() != NO_ID) {

			Connection conn = MainManager.getInstance().getPersistenceManager()
					.getDB_Connection();
			PreparedStatement ps = null;

			try {
				String sql = "update " + getTableName() + " set " + keyName
						+ "=? where " + getPrimaryKeyName() + "=" + getId();
				ps = conn.prepareStatement(sql);
				ps.setObject(1, param);
				ps.executeUpdate();
				return true;
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
						conn = null;
					}
					if (ps != null) {
						ps.close();
						ps = null;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		}// end if(如果有ID)

		return false;

	}

	/**
	 * 第一次持久化我
	 */
	public Long persisMeFirstTime() {
		try {
			
			//设置添加时间与更新时间
			setAddedDate(new Timestamp(System.currentTimeMillis()));
			setUpdateDate(new Timestamp(System.currentTimeMillis()));
			
			String sql = "insert into " + getTableName() + " ";
			String keys = "(";
			String values = "(";

			// 得到反射关联
			HashMap<String, RelevanceBean> reflectRelevance = getReflectRelevance();
			// System.out.println("param size=" + reflectRelevance.size());
			// 得到反射关联迭代器
			Iterator iterRR = reflectRelevance.entrySet().iterator();
			boolean isFirst = true;
			// 值队列
			List listValue = new ArrayList<Object>();
			// 迭代
			while (iterRR.hasNext()) {
				Map.Entry entry = (Map.Entry) iterRR.next();
				String key = (String) entry.getKey();
				RelevanceBean rBean = (RelevanceBean) entry.getValue();
				// 得到数据库字段所对应的值
				String paramName = rBean.getParamName();
				// 因为是第一次持久化，所以不能保存主键
				if (!key.equals(getPrimaryKeyName())) {
					// 改变参数首字母为大写
					paramName = "get"
							+ ReflectionBasic.changeHeadLetterUpper(paramName);

					// 填充该对象的参数

					Object value = ReflectionBasic.invokeMethod(this,
							paramName, null);
					// System.out.println("paramKey=" + paramName + ";value=" +
					// value);
					if (value != null) {
						listValue.add(value);
						if (!isFirst) {
							keys += ",";
							values += ",";
						}
						keys += key;
						values += "?";
						isFirst = false;
					}
				}// end if(因为是第一次持久化，所以不能保存主键)
			}// end while(迭代)

			keys += ")";
			values += ")";
			sql += keys + " values " + values;

			System.out.println(sql);

			Connection conn = MainManager.getInstance().getPersistenceManager()
					.getDB_Connection();
			PreparedStatement ps = null;

			try {
				ps = conn
						.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

				// 得到值并赋予语句中
				int iLength = listValue.size();
				for (int i = 1; i <= iLength; i++) {
					System.out.println(listValue.get(i - 1));
					ps.setObject(i, listValue.get(i - 1));
				}

				ps.executeUpdate();
				ResultSet rs = ps.getGeneratedKeys();
				if (rs.next()) {
					long lID = rs.getInt(1);
					setId(lID);
					return lID;
				}
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
						conn = null;
					}
					if (ps != null) {
						ps.close();
						ps = null;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 持久化我
	 */
	public boolean persisMe() {
		Connection conn = MainManager.getInstance().getPersistenceManager()
				.getDB_Connection();
		PreparedStatement ps = null;
		try {
			String sql = "update " + getTableName() + " set ";

			// 得到反射关联
			HashMap<String, RelevanceBean> reflectRelevance = getReflectRelevance();
			// System.out.println("param size=" + reflectRelevance.size());
			// 得到反射关联迭代器
			Iterator iterRR = reflectRelevance.entrySet().iterator();
			boolean isFirst = true;
			// 值队列
			List listValue = new ArrayList<Object>();
			// 迭代
			while (iterRR.hasNext()) {

				Map.Entry entry = (Map.Entry) iterRR.next();
				String key = (String) entry.getKey();
				RelevanceBean rBean = (RelevanceBean) entry.getValue();
				// 得到数据库字段所对应的值
				String paramName = rBean.getParamName();
				// 因为是第一次持久化，所以不能保存主键
				if (!key.equals(getPrimaryKeyName())) {
					// 改变参数首字母为大写
					paramName = "get"
							+ ReflectionBasic.changeHeadLetterUpper(paramName);

					// 填充该对象的参数

					Object value = ReflectionBasic.invokeMethod(this,
							paramName, null);
					// System.out.println("paramKey=" + paramName + ";value=" +
					// value);
					if (value != null) {
						listValue.add(value);
						if (!isFirst) {
							sql += ",";
						}
						sql += key + "=? ";
						isFirst = false;
					}
				}// end if(因为是第一次持久化，所以不能保存主键)
			}// end while(迭代)

			sql += " where " + getPrimaryKeyName() + "=" + getId();

			// System.out.println(sql);

			ps = conn.prepareStatement(sql);
			// 得到值并赋予语句中
			int iLength = listValue.size();
			for (int i = 1; i <= iLength; i++) {
				// System.out.println(listValue.get(i - 1));
				ps.setObject(i, listValue.get(i - 1));
			}
			ps.executeUpdate();

			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				if (conn != null) {
					conn.close();
					conn = null;
				}
				if (ps != null) {
					ps.close();
					ps = null;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return false;
	}

	@Override
	public String toString() {
		if (reflectRelevance.size() == 0) {
			return "我没有数据-----";
		} else {
			StringBuffer sb = new StringBuffer();

			// 得到反射关联
			HashMap<String, RelevanceBean> reflectRelevance = getReflectRelevance();
//			System.out.println("param size=" + reflectRelevance.size());
			// 得到反射关联迭代器
			Iterator iterRR = reflectRelevance.entrySet().iterator();
			// 迭代
			while (iterRR.hasNext()) {
				Map.Entry entry = (Map.Entry) iterRR.next();
				String key = (String) entry.getKey();
				RelevanceBean rBean = (RelevanceBean) entry.getValue();
				// 得到数据库字段所对应的值
				String paramName = rBean.getParamName();
				// 改变参数首字母为大写
				paramName = "get"
						+ ReflectionBasic.changeHeadLetterUpper(paramName);

				// 填充该对象的参数
				try {
					Object value = ReflectionBasic.invokeMethod(this,
							paramName, null);
					// System.out.println("paramKey=" + paramName + ";value=" +
					// value);
					sb.append(key + " = " + value + ";");

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}// end while(迭代)

			return sb.toString();
		}
	}

}
